package data

import (
	"database/sql"
	"github.com/astaxie/beego"
	_ "github.com/lib/pq"
	"github.com/qiniu/log"
)

const (
	KEY_DB_URL         = "database::dburl"
	KEY_DB_TYPE        = "database::dbname"
	DEFULT_SILENCE_LEN = 10
)

var db *sql.DB

func init() {
	dbtype := beego.AppConfig.String(KEY_DB_TYPE)
	dburl := beego.AppConfig.String(KEY_DB_URL)
	var err error
	db, err = sql.Open(dbtype, dburl)
	if err != nil {
		log.Fatal(err)
	}
	err = db.Ping()
	if err != nil {
		log.Fatal(err)
	}
}

type DataAccess interface {
	Add(data interface{}) bool
	/*
		Del(data interface) bool
		DelById(int id) bool
		Update(data interface{}) bool
		Select(data interface{}) bool
		SelectById(id int)interface{}*/
}
type HotspotAccess struct {
}

func (ha *HotspotAccess) Add(hs *Hotspot) (bool, error) {
	stmt, err := db.Prepare("insert into hotspots(tag,lat,lng) values($1,$2,$3)")
	if err != nil {
		return false, err
	}
	defer stmt.Close()
	_, err = stmt.Exec(hs.Tag, hs.Lat, hs.Lng)
	if err != nil {
		return false, err
	}
	return true, nil
}
func (ha *HotspotAccess) NearBy(c *Circle) ([]*Hotspot, error) {
	stmt, err := db.Prepare("select id,tag,lat,lng from hotspots where earth_box(ll_to_earth($1,$2),$3) @> ll_to_earth(lat,lng) ")
	if err != nil {
		return nil, err
	}
	defer stmt.Close()		
	rows, err := stmt.Query(c.Lat, c.Lng, c.Radius)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	result := make([]*Hotspot, DEFULT_SILENCE_LEN)
	var cur int
	for cur = 0; rows.Next(); cur++ {
		item := &Hotspot{}
		err = rows.Scan(&item.Id, &item.Tag, &item.Lat, &item.Lng)
		if err != nil {
			return nil, err
		}
		if cur < len(result) {
			result[cur] = item
		} else {
			result = append(result, item)
		}
	}
	return result[0:cur], nil
}
